package org.thomias.swtmultithread.startstop;

import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.thomias.loggertest.YT;
import org.eclipse.swt.widgets.Label;

public class Application extends ApplicationWindow {

	protected static final String STOP = "Stop";
	protected static final String START = "Restart";
	public Button btn;
	private StopAction stopAction;
	private StartAction startAction;
	public ProgressBar progressBar;
	public BarThread bu;
	public int i;
	public AppMonitor m;
	private Label label;
	private Label lblElapse;
	private Label lblEstimated;
	private long started;

	public Application() {
		super(null);
		i = 0;
		createActions();
		addToolBar(SWT.FLAT | SWT.WRAP);
		addMenuBar();
		addStatusLine();
	}

	@Override
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(null);

		progressBar = new ProgressBar(container, SWT.NONE);
		progressBar.setBounds(10, 65, 414, 17);
		progressBar.setMinimum(0);
		progressBar.setMaximum(100);

		btn = new Button(container, SWT.NONE);
		btn.setBounds(187, 10, 55, 25);
		btn.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (btn.getText().equals(STOP)) {
					stopAction.run();
					btn.setText(START);
				} else if (btn.getText().equals(START)) {
					startAction.run();
					btn.setText(STOP);
				}
			}
		});
		btn.setText(STOP);

		label = new Label(container, SWT.NONE);
		label.setAlignment(SWT.CENTER);
		label.setBounds(187, 90, 55, 15);
		label.setText("0%");

		lblElapse = new Label(container, SWT.NONE);
		lblElapse.setBounds(10, 129, 185, 15);
		lblElapse.setText("Elapse: ");

		lblEstimated = new Label(container, SWT.NONE);
		lblEstimated.setBounds(10, 150, 185, 15);
		lblEstimated.setText("Estimated:");
		m = new AppMonitor();
		m.addTask(new Runnable() {
			@Override
			public void run() {
				updateProgressBar();
			}
		});
		m.addTask(new Runnable() {
			@Override
			public void run() {
				updateLabel();
			}
		});
		m.addTask(new Runnable() {
			@Override
			public void run() {
				updateTime();
			}
		});
		started = System.currentTimeMillis();
		m.start();
		startAction.run();
		return container;
	}

	private void createActions() {
		startAction = new StartAction(this);
		stopAction = new StopAction(this);
	}

	@Override
	protected MenuManager createMenuManager() {
		MenuManager menuManager = new MenuManager("menu");
		return menuManager;
	}

	@Override
	protected ToolBarManager createToolBarManager(int style) {
		ToolBarManager toolBarManager = new ToolBarManager(style);
		return toolBarManager;
	}

	@Override
	protected StatusLineManager createStatusLineManager() {
		StatusLineManager statusLineManager = new StatusLineManager();
		return statusLineManager;
	}

	public static void main(String args[]) {
		try {
			YT.init();
			Application window = new Application();
			window.setBlockOnOpen(true);
			window.open();
			Display.getCurrent().dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("New Application");
	}

	@Override
	protected Point getInitialSize() {
		return new Point(450, 300);
	}

	public void updateTime() {
		getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				if (lblElapse.isDisposed() || lblEstimated.isDisposed()) {
					return;
				}
				double elapsed = (System.currentTimeMillis() - started) / 1000;
				lblElapse.setText("Elapsed: " + (long) elapsed + "s");
				if (i == 0) {
					lblEstimated.setText("Estimated: N/A");
				} else {
					int left = 100 - i;
					int remaining = (int) (((double) elapsed / (double) i) * left);
					lblEstimated.setText("Estimated: " + remaining + "s");
				}
			}
		});
	}

	public void updateLabel() {
		getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				if (label.isDisposed()) {
					return;
				}
				label.setText(i + "%");
			}
		});
	}

	public void updateProgressBar() {
		getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				if (progressBar.isDisposed()) {
					return;
				}
				progressBar.setSelection(i);
			}
		});
	}
}
